package com.xinchuang.utils;

import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlCursor;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;

/**
 * @author: 570
 * @createTime: 2023-09-19 21:26
 * @description: word操作工具类
 */
public class WordGrtUtil {

    public static void setTableValue(String storePath, List<Map<String, String>> subList) throws IOException {
        File file = new File(storePath);
        InputStream is = Files.newInputStream(file.toPath());
        XWPFDocument doc = new XWPFDocument(is);
        List<XWPFTable> tables = doc.getTables();
        for (int i = 1; i < tables.size(); i++) {
            XWPFTable table = tables.get(i);
            Map<String, String> map = subList.get( i - 1 );
            setContentCellValue(map,table);
        }
        OutputStream os = Files.newOutputStream(Paths.get(storePath));
        doc.write(os);
        close(os);
        close(is);
    }

    private static void setContentCellValue(Map<String, String> subMap, XWPFTable table) {
        XWPFTableRow row1 = table.getRows().get(1);
        row1.getCell(row1.getTableCells().size()-1).setText(getMapValue(subMap,"子MB名称" ));
        XWPFTableRow row2 = table.getRows().get(2);
        row2.getCell(row2.getTableCells().size()-1).setText(getMapValue(subMap,"子MB类型" ));
        XWPFTableRow row3 = table.getRows().get(3);
        row3.getCell(row3.getTableCells().size()-1).setText(getMapValue(subMap,"经度" ));
        XWPFTableRow row4 = table.getRows().get(3);
        row4.getCell(row4.getTableCells().size()-1).setText(getMapValue(subMap,"纬度" ));
        XWPFTableRow row5 = table.getRows().get(3);
        row5.getCell(row5.getTableCells().size()-1).setText(getMapValue(subMap,"大地高" ));
        XWPFTableRow row6 = table.getRows().get(3);
        row6.getCell(row6.getTableCells().size()-1).setText(getMapValue(subMap,"海拔高" ));
        XWPFTableRow row7 = table.getRows().get(3);
        row7.getCell(row7.getTableCells().size()-1).setText(getMapValue(subMap,"点位误差" ));
        XWPFTableRow row8 = table.getRows().get(3);
        row8.getCell(row8.getTableCells().size()-1).setText(getMapValue(subMap,"纬度误差" ));
        XWPFTableRow row9 = table.getRows().get(3);
        row9.getCell(row9.getTableCells().size()-1).setText(getMapValue(subMap,"经度误差" ));
        XWPFTableRow row10 = table.getRows().get(3);
        row10.getCell(row10.getTableCells().size()-1).setText(getMapValue(subMap,"大地高误差" ));
        XWPFTableRow row11 = table.getRows().get(3);
        row11.getCell(row11.getTableCells().size()-1).setText(getMapValue(subMap,"海拔误差" ));
        XWPFTableRow row12 = table.getRows().get(3);
        row12.getCell(row12.getTableCells().size()-1).setText(getMapValue(subMap,"原图误差" ));
        XWPFTableRow row13 = table.getRows().get(3);
        row13.getCell(row13.getTableCells().size()-1).setText(getMapValue(subMap,"面积" ));
        XWPFTableRow row14 = table.getRows().get(3);
        row14.getCell(row14.getTableCells().size()-1).setText(getMapValue(subMap,"结构" ));
        XWPFTableRow row15 = table.getRows().get(3);
        row15.getCell(row15.getTableCells().size()-1).setText(getMapValue(subMap,"子MB形状" ));
        XWPFTableRow row16 = table.getRows().get(3);
        row16.getCell(row16.getTableCells().size()-1).setText(getMapValue(subMap,"圆内半径" ));
        XWPFTableRow row17 = table.getRows().get(3);
        row17.getCell(row17.getTableCells().size()-1).setText(getMapValue(subMap,"圆外半径" ));
        XWPFTableRow row18 = table.getRows().get(3);
        row18.getCell(row18.getTableCells().size()-1).setText(getMapValue(subMap,"矩形长" ));
        XWPFTableRow row19 = table.getRows().get(3);
        row19.getCell(row19.getTableCells().size()-1).setText(getMapValue(subMap,"矩形宽" ));
        XWPFTableRow row20 = table.getRows().get(3);
        row20.getCell(row20.getTableCells().size()-1).setText(getMapValue(subMap,"矩形长方向夹角" ));
    }

    private static String getMapValue(Map<String, String> subMap, String key){
        return subMap.get( key )==null?"":subMap.get( key );
    }

    public static void copyTableByLoop(String srcPath, int srcTableIndex, int copyNum, String storePath) throws Exception {
        File file = new File(srcPath);
        InputStream is = Files.newInputStream(file.toPath());
        XWPFDocument doc = new XWPFDocument(is);
        XWPFTable sourceTable = doc.getTableArray(srcTableIndex);
        //复制的表格贴到第10个段落
        int i = 10;
        for(int j = 0; j < copyNum; j++){
            XWPFParagraph paragraph = doc.getParagraphs().get(i++);
            doc.insertNewParagraph(paragraph.getCTP().newCursor());
            insertTableInPara(sourceTable,doc,paragraph,false);
        }
        OutputStream os = Files.newOutputStream( Paths.get(storePath));
        doc.write(os);
        close(os);
        close(is);
    }

    /**
     * <b> 在段落中插入表格
     * </b><br><br><i>Description</i> : 表格单元格中建段落再插入表格，原段落会挤到下一个段落,用isDelNullPara控制删除空原段落，
     * isDelNullPara为true时要注意循环迭代，最好倒序循环para，插入表格后还有对para操作时也要注意，可能isDelNullPara要设为false
     * @param sourceTable 要插入的源表格
     * @param targetDoc 要插入的文档
     * @param  para 要插入表格的段落
     * @param  isDelNullPara 是否删除para为空是多出来的空段落
     * @return void
     */
    public static void insertTableInPara(XWPFTable sourceTable,XWPFDocument targetDoc,XWPFParagraph para,boolean isDelNullPara){
        XmlCursor cursor = para.getCTP().newCursor();
        XWPFTable tableOne = targetDoc.insertNewTbl(cursor);
        for(int i = 0; i < sourceTable.getRows().size(); i++){
            copy(tableOne,sourceTable.getRow(i),i+1);
        }
        if(isDelNullPara){
            if(para.getText() != null && para.getText().length() > 0){
            }else {
                targetDoc.removeBodyElement(targetDoc.getPosOfParagraph(para));
            }
        }
        tableOne.removeRow(0);
    }

    /**
     * <b> 复制表格
     * </b><br><br><i>Description</i> :
     * @param table, sourceRow, rowIndex
     * @return void
     */
    public static void copy(XWPFTable table, XWPFTableRow sourceRow, int rowIndex){
        //在表格指定位置新增一行
        XWPFTableRow targetRow = table.insertNewTableRow(rowIndex);
        //复制行属性
        targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
        List<XWPFTableCell> cellList = sourceRow.getTableCells();
        if (null == cellList) {
            return;
        }
        //复制列及其属性和内容
        XWPFTableCell targetCell = null;
        for (XWPFTableCell sourceCell : cellList) {
            targetCell = targetRow.addNewTableCell();
            //处理一个单元格内有多个段落
            List<XWPFParagraph> paragraphs = sourceCell.getParagraphs();
            if(paragraphs.size() > 1){
                for(int i = 1; i < paragraphs.size(); i++){
                    targetCell.addParagraph();
                }
            }
            //列属性
            targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
            //段落属性
            if(sourceCell.getParagraphs()!=null&&sourceCell.getParagraphs().size()>0){
                for(int i = 0; i < sourceCell.getParagraphs().size();i++){
                    targetCell.getParagraphs().get(i).getCTP().setPPr(sourceCell.getParagraphs().get(i).getCTP().getPPr());
                    if(sourceCell.getParagraphs().get(i).getRuns()!=null&&sourceCell.getParagraphs().get(i).getRuns().size()>0){
                        for(int j = 0; j < sourceCell.getParagraphs().get(i).getRuns().size(); j++){
                            XWPFRun cellR = targetCell.getParagraphs().get(i).createRun();
                            cellR.setText(sourceCell.getParagraphs().get(i).getRuns().get(j).getText(0));
                            cellR.setBold(sourceCell.getParagraphs().get(i).getRuns().get(j).isBold());
                            cellR.setColor(sourceCell.getParagraphs().get(i).getRuns().get(j).getColor());
                            if(sourceCell.getParagraphs().get(i).getRuns().get(j).getFontSize() == -1){
                                cellR.setFontSize(10);
                            }else {
                                cellR.setFontSize(sourceCell.getParagraphs().get(i).getRuns().get(j).getFontSize());
                            }
                            cellR.setCapitalized(sourceCell.getParagraphs().get(i).getRuns().get(j).isCapitalized());
                            cellR.setDoubleStrikethrough(sourceCell.getParagraphs().get(i).getRuns().get(j).isDoubleStrikeThrough());
                            cellR.setEmbossed(sourceCell.getParagraphs().get(i).getRuns().get(j).isEmbossed());
                            cellR.setFontFamily(sourceCell.getParagraphs().get(i).getRuns().get(j).getFontFamily());
                            cellR.setImprinted(sourceCell.getParagraphs().get(i).getRuns().get(j).isImprinted());
                            cellR.setItalic(sourceCell.getParagraphs().get(i).getRuns().get(j).isItalic());
                            cellR.setKerning(sourceCell.getParagraphs().get(i).getRuns().get(j).getKerning());
                            cellR.setShadow(sourceCell.getParagraphs().get(i).getRuns().get(j).isShadowed());
                            cellR.setStrikeThrough(sourceCell.getParagraphs().get(i).getRuns().get(j).isStrikeThrough());
                            cellR.setSmallCaps(sourceCell.getParagraphs().get(i).getRuns().get(j).isSmallCaps());
                            cellR.setSubscript(sourceCell.getParagraphs().get(i).getRuns().get(j).getSubscript());
                            cellR.setTextPosition(sourceCell.getParagraphs().get(i).getRuns().get(j).getTextPosition());
                            cellR.setUnderline(sourceCell.getParagraphs().get(i).getRuns().get(j).getUnderline());
                        }
                    }else{
                        targetCell.setText(sourceCell.getText());
                    }
                }

            }else{
                targetCell.setText(sourceCell.getText());
            }
        }
    }

    /**
     * 关闭输出流
     *
     * @param os
     */
    private static void close(OutputStream os) {
        if (os != null) {
            try {
                os.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 关闭输入流
     *
     * @param is
     */
    private static void close(InputStream is) {
        if (is != null) {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
